home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / formats / iff / newiff.lzh / NewIFF / NewIFF.lzh / newiff / modules / screen.c < prev    next >
C/C++ Source or Header  |  1992-05-18  |  12KB  |  406 lines

  1. /* screen.c - 2.0 screen module for Display
  2.  * based on scdemo, oscandemo, looki
  3.  * 10/91 - added public screen support by checking user screen tags
  4.  * for SA_PubScreen and setting screen public if found.
  5.  */
  6.  
  7. /*
  8. Copyright (c) 1989, 1990 Commodore-Amiga, Inc.
  9.  
  10. Executables based on this information may be used in software
  11. for Commodore Amiga computers. All other rights reserved.
  12. This information is provided "as is"; no warranties are made.
  13. All use is at your own risk, and no liability or responsibility
  14. is assumed.
  15. */
  16. #define INTUI_V36_NAMES_ONLY
  17.  
  18. #include "iffp/ilbmapp.h"
  19.  
  20. BOOL   VideoControlTags(struct ColorMap *,ULONG tags, ...);
  21.  
  22. extern struct Library *GfxBase;
  23. extern struct Library *IntuitionBase;
  24.  
  25. struct TextAttr SafeFont = { (UBYTE *) "topaz.font", 8, 0, 0, };
  26. UWORD  penarray[] = {~0};
  27.  
  28. /* default new window if none supplied in ilbm->nw */
  29. struct   NewWindow      defnw = {
  30.    0, 0,                                  /* LeftEdge and TopEdge */
  31.    0, 0,                                /* Width and Height */
  32.    -1, -1,                                /* DetailPen and BlockPen */
  33.    IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS, /* IDCMP Flags with Flags below */
  34.    WFLG_BACKDROP | WFLG_BORDERLESS |
  35.    WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH |
  36.    WFLG_ACTIVATE | WFLG_RMBTRAP,
  37.    NULL, NULL,                            /* Gadget and Image pointers */
  38.    NULL,                                  /* Title string */
  39.    NULL,                                  /* Screen ptr null till opened */
  40.    NULL,                                  /* BitMap pointer */
  41.    50, 20,                                /* MinWidth and MinHeight */
  42.    0 , 0,                                 /* MaxWidth and MaxHeight */
  43.    CUSTOMSCREEN                           /* Type of window */
  44.    };
  45.  
  46.  
  47. /* opendisplay - passed ILBMInfo, dimensions, modeID
  48.  *
  49.  *    Attempts to open correct 2.0 modeID screen and window,
  50.  *    else an old 1.3 mode screen and window.
  51.  *
  52.  * Returns *window or NULL.
  53.  */
  54.  
  55. struct Window *opendisplay(struct ILBMInfo *ilbm,
  56.                SHORT wide, SHORT high, SHORT deep,
  57.                ULONG mode)
  58.     {
  59.     struct NewWindow newwin, *nw;
  60.  
  61.     closedisplay(ilbm);
  62.     if(ilbm->scr = openidscreen(ilbm, wide, high, deep, mode))
  63.     {
  64.     nw = &newwin;
  65.     if(ilbm->windef) *nw = *(ilbm->windef);
  66.     else *nw = *(&defnw);
  67.     nw->Screen    = ilbm->scr;
  68.  
  69.     D(bug("sizes: scr= %ld x %ld  passed= %ld x %ld\n",
  70.         ilbm->scr->Width,ilbm->scr->Height,wide,high)); 
  71.  
  72.     nw->Width    = wide;
  73.     nw->Height    = high;
  74.     if (!(ilbm->win = OpenWindow(nw)))
  75.         {
  76.         closedisplay(ilbm);
  77.         D(bug("Failed to open window."));
  78.         }
  79.     else
  80.         {
  81.         if(ilbm->win->Flags & WFLG_BACKDROP)
  82.         {
  83.         ShowTitle(ilbm->scr, FALSE);
  84.         ilbm->TBState = FALSE;
  85.         }
  86.         }
  87.     }
  88.  
  89.     if(ilbm->scr)    /* nulled out by closedisplay if OpenWindow failed */
  90.     {
  91.     ilbm->vp  = &ilbm->scr->ViewPort;
  92.     ilbm->srp = &ilbm->scr->RastPort;
  93.     ilbm->wrp = ilbm->win->RPort;
  94.     }
  95.     return(ilbm->win);
  96.     }
  97.  
  98.  
  99. /* Under 2.0, returns result of CloseScreen (TRUE for successful close)
  100.  * Under 1.3, always returns TRUE
  101.  */
  102. BOOL closedisplay(struct ILBMInfo *ilbm)
  103.     {
  104.     extern struct Library *IntuitionBase;
  105.     BOOL temp, result = TRUE;
  106.  
  107.     if(ilbm)
  108.     {
  109.         if(ilbm->win)    CloseWindow(ilbm->win), ilbm->win=NULL, ilbm->wrp=NULL;
  110.     if(ilbm->scr)
  111.         {
  112.         if(ilbm->scr->Flags & PUBLICSCREEN)
  113.         {
  114.         if(((struct Library *)IntuitionBase)->lib_Version >= 36)
  115.             PubScreenStatus(ilbm->scr, PSNF_PRIVATE);
  116.         }
  117.         temp = CloseScreen(ilbm->scr);
  118.         if(IntuitionBase->lib_Version >= 36)  result = temp;
  119.         if(result)
  120.         {
  121.         ilbm->scr = NULL;    
  122.             ilbm->vp  = NULL;
  123.             ilbm->srp = NULL;
  124.         }
  125.         }
  126.     }
  127.     return(result);
  128.     }
  129.  
  130.  
  131.  
  132. /* openidscreen - ILBMInfo, dimensions, modeID
  133.  *
  134.  *    Attempts to open correct 2.0 modeID screen with centered
  135.  *    overscan based on user's prefs,
  136.  *    else old 1.3 mode screen.
  137.  *
  138.  * If ilbm->stype includes CUSTOMBITMAP, ilbm->brbitmap will be
  139.  *       used as the screen's bitmap.
  140.  * If ilbm->stags is non-NULL, these tags will be added to the
  141.  *    end of the taglist.
  142.  *
  143.  * Returns *screen or NULL.
  144.  */
  145.  
  146. struct Screen *openidscreen(struct ILBMInfo *ilbm,
  147.                 SHORT wide, SHORT high, SHORT deep,
  148.                 ULONG mode)
  149.     {
  150.     struct NewScreen ns;            /* for old style OpenScreen */
  151.     struct Rectangle spos, dclip, txto, stdo, maxo, uclip;  /* display rectangles */
  152.     struct Rectangle *uclipp;
  153.     struct Screen   *scr = NULL;
  154.     LONG   error, trynew;
  155.     ULONG  bitmaptag, passedtags;
  156.     BOOL   vctl;
  157.  
  158.     if (trynew = ((((struct Library *)GfxBase)->lib_Version >= 36)&&
  159.           (((struct Library *)IntuitionBase)->lib_Version >= 36)))
  160.     {
  161.         /* if >= v36, see if mode is available */
  162.     if(error = ModeNotAvailable(mode))
  163.         {
  164.         D(bug("Mode $%08lx not available, error=%ld:\n",mode,error));
  165.         /* if not available, try fall back mode */
  166.         mode = modefallback(mode,wide,high,deep);
  167.         error = ModeNotAvailable(mode);
  168.  
  169.         D(bug("$%08lx ModeNotAvailable=%ld:\n",mode,error));
  170.         }
  171.  
  172.     if(error) trynew = FALSE;
  173.     else trynew=((QueryOverscan(mode,&txto,OSCAN_TEXT))&&
  174.             (QueryOverscan(mode,&stdo,OSCAN_STANDARD))&&
  175.                 (QueryOverscan(mode,&maxo,OSCAN_MAX)));
  176.     }
  177.  
  178.     D(bug("\nILBM: w=%ld, h=%ld, d=%ld, mode=0x%08lx\n",
  179.         wide,high,deep,mode));    
  180.     D(bug("OPEN: %s.\n",
  181.         trynew    ? "Is >= 2.0 and mode available, trying OpenScreenTags"
  182.         : "Not 2.0, doing old OpenScreen"));
  183.  
  184.     if(trynew)
  185.     {
  186.     /* If user clip type specified and available, use it */
  187.     if(ilbm->Video) ilbm->ucliptype = OSCAN_VIDEO;
  188.     if((ilbm->ucliptype)&&(QueryOverscan(mode,&uclip,ilbm->ucliptype)))
  189.         uclipp = &uclip;
  190.     else uclipp = NULL;
  191.  
  192.     clipit(wide,high,&spos,&dclip,&txto,&stdo,&maxo,uclipp);
  193.  
  194.     D(bug("Using dclip  %ld,%ld  to  %ld,%ld... width=%ld height=%ld\n",
  195.             dclip.MinX,dclip.MinY,dclip.MaxX,dclip.MaxY,
  196.             dclip.MaxX-dclip.MinX+1,dclip.MaxY-dclip.MinY+1));
  197.     D(bug("spos->minx = %ld, spos->miny = %ld\n",spos.MinX,spos.MinY));
  198.     D(bug("DEBUG: About to attempt OpenScreenTags\n"));
  199.  
  200.     bitmaptag = ((ilbm->brbitmap)&&(ilbm->stype & CUSTOMBITMAP)) ?
  201.         SA_BitMap : TAG_IGNORE;
  202.     passedtags = ilbm->stags ? TAG_MORE : TAG_IGNORE;
  203.  
  204.     scr=(struct Screen *)OpenScreenTags((struct NewScreen *)NULL,
  205.         SA_DisplayID,    mode,
  206.         SA_Type,    ilbm->stype,
  207.         SA_Behind,    TRUE,
  208.         SA_Top,        spos.MinY,
  209.         SA_Left,    spos.MinX,
  210.         SA_Width,    wide,
  211.         SA_Height,    high,
  212.         SA_Depth,    deep,
  213.         SA_DClip,    &dclip,
  214.         SA_AutoScroll,    ilbm->Autoscroll ? TRUE : FALSE,
  215.         SA_Title,    ilbm->stitle,
  216.         SA_Font,    &SafeFont,
  217.         SA_Pens,    penarray,
  218.         SA_ErrorCode,    &error,
  219.         bitmaptag,    ilbm->brbitmap,
  220.         passedtags,    ilbm->stags,
  221.         TAG_DONE
  222.         );
  223.  
  224.         D(bug("DEBUG: OpenScreenTags scr at 0x%lx\n",scr));
  225.  
  226.         if(scr)
  227.         {
  228.         /* If caller specified a public screen, open for business */
  229.         if(scr->Flags & PUBLICSCREEN)
  230.             {
  231.             if(((struct Library *)IntuitionBase)->lib_Version >= 36)
  232.                 PubScreenStatus(scr,NULL);
  233.             }
  234.         if(ilbm->Notransb)
  235.             {
  236.             vctl=VideoControlTags(scr->ViewPort.ColorMap,
  237.                 VTAG_BORDERNOTRANS_SET, TRUE,
  238.                 TAG_DONE);
  239.  
  240.     D(bug("VideoControl to set bordernotrans, error = %ld\n",vctl));
  241.  
  242.             MakeScreen(scr);
  243.             RethinkDisplay();
  244.             }
  245.         }
  246.         else message("%s\n",openScreenErr(error));
  247.         }
  248.  
  249.     if(!scr)
  250.     {
  251.     /* ns initialization for 1.3 old style OpenScreen only
  252.          */
  253.     ns.LeftEdge = ns.TopEdge = 0;   
  254.     ns.Width     =    wide;
  255.     ns.Height     =    high;
  256.     ns.Depth    =    deep;
  257.     ns.ViewModes    =     modefallback(mode,wide,high,deep);
  258.     ns.DetailPen    =    0;
  259.     ns.BlockPen    =    1;
  260.     ns.Gadgets    =    NULL;
  261.     ns.CustomBitMap    =    ((ilbm->brbitmap)&&(ilbm->stype & CUSTOMBITMAP))
  262.                     ? ilbm->brbitmap : NULL;
  263.     ns.Font        =    &SafeFont;
  264.     ns.DefaultTitle =     ilbm->stitle;
  265.     ns.Type        =    ilbm->stype & 0x01FF;  /* allow only 1.3 types */
  266.  
  267.     scr=(struct Screen *)OpenScreen(&ns);
  268.  
  269.     D(bug("DEBUG: ns.ViewModes=0x%lx, vp->Modes=0x%lx\n",
  270.                  ns.ViewModes,scr->ViewPort.Modes));
  271.     D(bug("DEBUG: non-extended scr at 0x%lx (0=failure)\n",scr));
  272.     }
  273.     return(scr);
  274.     }
  275.  
  276.  
  277. /*
  278.  * modefallback - passed a mode id, attempts to provide a
  279.  *                suitable old mode to use instead
  280.  */
  281.  
  282. /* for old 1.3 screens */
  283. #define MODE_ID_MASK (LACE|HIRES|HAM|EXTRA_HALFBRITE)
  284.  
  285. ULONG modefallback(ULONG mode, SHORT wide, SHORT high, SHORT deep)
  286. {
  287. ULONG newmode;
  288.  
  289.     /* For now, simply masks out everything but old mode bits.
  290.      * This is just a cheap way to get some kind of display open
  291.      *   and may be totally invalid for future modes.
  292.      * Should search the display database for a suitable mode
  293.      * based on the specific needs of your application.
  294.      */
  295.     newmode = mode & MODE_ID_MASK;
  296.  
  297.     D(bug("Try 0x%08lx instead of 0x%08lx\n",newmode,mode));
  298.     return(newmode);
  299. }
  300.  
  301.  
  302. /*
  303.  * clipit - passed width and height of a display, and the text, std, and
  304.  *          max overscan rectangles for the mode, clipit fills in the
  305.  *          spos (screen pos) and dclip rectangles to use in centering.
  306.  *          Centered around smallest containing user-editable oscan pref,
  307.  *          with dclip confined to legal maxoscan limits.
  308.  *          Screens which center such that their top is below text
  309.  *          oscan top, will be moved up.
  310.  *          If a non-null uclip is passed, that clip is used instead.
  311.  */
  312. void clipit(SHORT wide, SHORT high,
  313.         struct Rectangle *spos, struct Rectangle *dclip,
  314.         struct Rectangle *txto, struct Rectangle *stdo,
  315.         struct Rectangle *maxo, struct Rectangle *uclip)
  316. {
  317. struct  Rectangle *besto;
  318. SHORT    minx, maxx, miny, maxy;
  319. SHORT    txtw, txth, stdw, stdh, maxw, maxh, bestw, besth;
  320.  
  321.     /* get the txt, std and max widths and heights */
  322.     txtw = txto->MaxX - txto->MinX + 1;
  323.     txth = txto->MaxY - txto->MinY + 1;
  324.     stdw = stdo->MaxX - stdo->MinX + 1;
  325.     stdh = stdo->MaxY - stdo->MinY + 1;
  326.     maxw = maxo->MaxX - maxo->MinX + 1;
  327.     maxh = maxo->MaxY - maxo->MinY + 1;
  328.  
  329.     if((wide <= txtw)&&(high <= txth))
  330.     {
  331.     besto = txto;
  332.     bestw = txtw;
  333.     besth = txth;
  334.  
  335.     D(bug("Best clip is txto\n"));
  336.     }
  337.     else
  338.     {
  339.     besto = stdo;
  340.     bestw = stdw;
  341.     besth = stdh;
  342.  
  343.     D(bug("Best clip is stdo\n"));
  344.     }
  345.  
  346.     D(bug("TXTO: mnx=%ld mny=%ld mxx=%ld mxy=%ld  stdw=%ld stdh=%ld\n",
  347.         txto->MinX,txto->MinY,txto->MaxX,txto->MaxY,txtw,txth));
  348.     D(bug("STDO: mnx=%ld mny=%ld mxx=%ld mxy=%ld  stdw=%ld stdh=%ld\n",
  349.         stdo->MinX,stdo->MinY,stdo->MaxX,stdo->MaxY,stdw,stdh));
  350.     D(bug("MAXO: mnx=%ld mny=%ld mxx=%ld mxy=%ld  maxw=%ld maxh=%ld\n",
  351.         maxo->MinX,maxo->MinY,maxo->MaxX,maxo->MaxY,maxw,maxh));
  352.  
  353.     if(uclip)
  354.     {
  355.     *dclip = *uclip;
  356.         spos->MinX = uclip->MinX;
  357.     spos->MinY = uclip->MinY;
  358.  
  359.     D(bug("UCLIP: mnx=%ld mny=%ld maxx=%ld maxy=%ld\n",
  360.             dclip->MinX,dclip->MinY,dclip->MaxX,dclip->MaxY));
  361.     }
  362.     else
  363.     {
  364.     /* CENTER the screen based on best oscan prefs
  365.      * but confine dclip within max oscan limits
  366.      *
  367.      * FIX MinX first */
  368.     spos->MinX = minx = besto->MinX - ((wide - bestw) >> 1);
  369.     maxx = wide + minx - 1;
  370.     if(maxx > maxo->MaxX)  maxx = maxo->MaxX;    /* too right */
  371.     if(minx < maxo->MinX)  minx = maxo->MinX;    /* too left  */
  372.  
  373.     D(bug("DCLIP: minx adjust from %ld to %ld\n",spos->MinX,minx));
  374.  
  375.     /* FIX MinY */
  376.     spos->MinY = miny = besto->MinY - ((high - besth) >> 1);
  377.     /* if lower than top of txto, move up */
  378.     spos->MinY = miny = MIN(spos->MinY,txto->MinY);
  379.     maxy = high + miny - 1;
  380.     if(maxy > maxo->MaxY)  maxy = maxo->MaxY;    /* too down  */
  381.     if(miny < maxo->MinY)  miny = maxo->MinY;    /* too up    */
  382.  
  383.     D(bug("DCLIP: miny adjust from %ld to %ld\n",spos->MinY,miny));
  384.  
  385.     /* SET up dclip */
  386.     dclip->MinX = minx;
  387.     dclip->MinY = miny;
  388.     dclip->MaxX = maxx;
  389.     dclip->MaxY = maxy;
  390.  
  391.     D(bug("CENTER: mnx=%ld mny=%ld maxx=%ld maxy=%ld\n",
  392.             dclip->MinX,dclip->MinY,dclip->MaxX,dclip->MaxY));
  393.     }
  394. }
  395.  
  396. /*----------------------------------------------------------------------*/
  397.  
  398. BOOL VideoControlTags(struct ColorMap *cm, ULONG tags, ...)
  399.     {
  400.     return (VideoControl(cm, (struct TagItem *)&tags));
  401.     }
  402.  
  403.  
  404. /*----------------------------------------------------------------------*/
  405.  
  406.